﻿using System;
using System.Runtime.Caching;
using System.Collections.Generic;
using System.Text.RegularExpressions;

namespace FrameWork.Core.Caching
{
    public class MemoryCacheManager : ICacheManager, IDisposable
    {
        public MemoryCacheManager() { }

        public virtual void Clear()
        {
            foreach (KeyValuePair<string, object> pair in (IEnumerable<KeyValuePair<string, object>>)this.Cache)
            {
                this.Remove(pair.Key);
            }
        }

        public virtual void Dispose()
        {
        }

        public virtual T Get<T>(string key)
        {
            if (this.Cache.Contains(key, null))
                return (T)this.Cache[key];
            else
                return default(T);
        }

        public virtual bool IsSet(string key)
        {
            return this.Cache.Contains(key, null);
        }

        public virtual void Remove(string key)
        {
            this.Cache.Remove(key, null);
        }

        public virtual void RemoveByPattern(string pattern)
        {
            Regex regex = new Regex(pattern, RegexOptions.Singleline | RegexOptions.Compiled | RegexOptions.IgnoreCase);
            List<string> list = new List<string>();
            foreach (KeyValuePair<string, object> pair in (IEnumerable<KeyValuePair<string, object>>)this.Cache)
            {
                if (regex.IsMatch(pair.Key))
                {
                    list.Add(pair.Key);
                }
            }
            foreach (string str in list)
            {
                this.Remove(str);
            }
        }

        public virtual void Set(string key, object data, int cacheTime)
        {
            if (data != null)
            {
                CacheItemPolicy policy = new CacheItemPolicy
                {
                    AbsoluteExpiration = DateTime.Now + TimeSpan.FromMilliseconds((double)cacheTime)
                };
                this.Cache.Add(new CacheItem(key, data), policy);
            }
        }


        public virtual void Set(string key, object data)
        {
            if (data != null)
                if (this.Cache.Contains(key))
                {
                    this.Cache.Remove(key);
                    this.Cache.Add(new CacheItem(key, data), null);
                }
                else this.Cache.Add(new CacheItem(key, data), null);
        }
        public virtual void UpdateSet(string key, object data, int cacheTime)
        {
            if (data != null)
            {

                CacheItemPolicy policy = new CacheItemPolicy
                {
                    AbsoluteExpiration = DateTime.Now + TimeSpan.FromMilliseconds((double)cacheTime)
                };
                var cacheItem = this.Cache.GetCacheItem(key);
                if (cacheItem != null)
                {
                    cacheItem.Value = data;
                    this.Cache.Set(cacheItem, policy);
                }
                else
                {

                    this.Cache.Add(new CacheItem(key, data), policy);
                }
            }
        }

        protected ObjectCache Cache
        {
            get
            {
                return MemoryCache.Default;
            }
        }
    }
}
